﻿using M13.Game.World;
using M13.Utility;
using Newtonsoft.Json;
using QFramework;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

namespace M13.GameSystem
{
    public interface ISaveSystem : ISystem//打分：6
    {
        public void CreateNewSaveDirectory(SaveConfig saveConfig);
        public void SaveIntegrityChecking(string saveName);
        public void CreateRegionFile(string saveName, Vector2Int regionLocalCoord, byte[] regionData);
        public byte[] LoadRegionData(string saveName, Vector2Int regionLocalCoord);
        public List<SaveConfig> TraverseFolders(string path);
        public void DeleteSave(string saveName);
    }

    public class SaveSystem : AbstractSystem, ISaveSystem
    {

        private SaveSetting _setting;
        private RegionDataParser _regionDataParser;
        protected override void OnInit()
        {
            _setting = new SaveSetting("新的世界");
            _regionDataParser = new RegionDataParser();
            Debug.Log("存档路径：" + _setting.SaveDirectoryDataRootPath);

            //this.RegisterEvent<CreateNewSaveButtonEvent>((e) => CreateNewSaveDirectory(e.saveConfig, e.saveConfig.name));
        }

        #region =============================================存档相关操作=====================================

        /// <summary>
        /// 创建存档文件夹
        /// </summary>
        /// <param name="SaveConfig"></param>
        /// <param name="saveName"></param>
        public void CreateNewSaveDirectory(SaveConfig saveConfig)
        {
            Debug.Log(saveConfig.name + ";" + saveConfig.seed + ";" + saveConfig.saveId + ";" + saveConfig.time);
            if (saveConfig.name == null)
            {
                SaveIntegrityChecking(saveConfig.name);
                CreateSaveJsonTag(saveConfig, _setting.SaveDirectoryDataRootPath + "/" + saveConfig.name);
            }
            else
            {
                SaveIntegrityChecking(saveConfig.name);
                CreateSaveJsonTag(saveConfig, _setting.SaveDirectoryDataRootPath + "/" + saveConfig.name);
            }
        }

        /// <summary>
        /// 检测存档文件夹的完整性
        /// </summary>
        public void SaveIntegrityChecking(string saveName)
        {
            if (!Directory.Exists(_setting.SaveDirectoryDataRootPath))
                Directory.CreateDirectory(_setting.SaveDirectoryDataRootPath);

            if (!Directory.Exists(_setting.SaveDirectoryDataRootPath + "/" + saveName))
                Directory.CreateDirectory(_setting.SaveDirectoryDataRootPath + "/" + saveName);

            if (!Directory.Exists(_setting.SaveDirectoryDataRootPath + "/" + saveName + _setting.ChunkDirectoryDataPath))
                Directory.CreateDirectory(_setting.SaveDirectoryDataRootPath + "/" + saveName + _setting.ChunkDirectoryDataPath);

            Debug.Log(_setting.SaveDirectoryDataRootPath + "/" + saveName + _setting.ChunkDirectoryDataPath);
        }

        /// <summary>
        /// 遍历所有存档文件夹
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public List<SaveConfig> TraverseFolders(string path)
        {
            List<SaveConfig> saveDatas = new List<SaveConfig>();
            if (Directory.Exists(path))
            {
                string[] folders = Directory.GetDirectories(path);
                foreach (string folder in folders)
                {
                    if (File.Exists(Path.Combine(folder, "SaveConfig.json")))
                    {
                        SaveConfig saveConfig = ReadSaveJsonTag(folder);
                        saveDatas.Add(saveConfig);
                        Debug.LogFormat("加载的已有存档：{0},id为：{1}", saveConfig.name, saveConfig.saveId);
                    }
                }
            }

            return saveDatas;
        }

        /// <summary>
        /// 删除存档文件
        /// </summary>
        /// <param name="saveName"></param>
        public void DeleteSave(string saveName)
        {
            if (Directory.Exists(_setting.SaveDirectoryDataRootPath + "/" + saveName))
            {
                DirectoryInfo directoryInfo = new DirectoryInfo(_setting.SaveDirectoryDataRootPath + "/" + saveName);
                directoryInfo.Delete(true);
            }
            else Debug.Log("存档文件夹不存在，无法删除");
        }

        /// <summary>
        /// 创建存档json标签
        /// </summary>
        /// <param name="saveConfig"></param>
        /// <param name="path"></param>
        private void CreateSaveJsonTag(SaveConfig saveConfig, string path)
        {
            string jsonString = JsonUtility.ToJson(saveConfig);
            string filePath = Path.Combine(path, "SaveConfig.json");
            File.WriteAllText(filePath, jsonString);
        }

        /// <summary>
        /// 读取存档json标签
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        private SaveConfig ReadSaveJsonTag(string saveName)
        {
            SaveConfig data;
            string filePath = Path.Combine(saveName, "SaveConfig.json");
            string jsonString = File.ReadAllText(filePath);
            data = JsonConvert.DeserializeObject<SaveConfig>(jsonString);
            return data;
        }

        #endregion


        #region ===========================================世界相关操作=======================================

        /// <summary>
        /// 创建区域文件，初始化引导区数据
        /// </summary>
        public void CreateRegionFile(string saveName, Vector2Int regionLocalCoord, byte[] regionData)
        {
            string regionFileName = CoordToFileName(regionLocalCoord);
            if (!File.Exists(_setting.SaveDirectoryDataRootPath + "/" + saveName + _setting.ChunkDirectoryDataPath + "/" + regionFileName))
            {
                using (FileStream fs = File.Create(_setting.SaveDirectoryDataRootPath + "/" + saveName + _setting.ChunkDirectoryDataPath + "/" + regionFileName))
                {
                    fs.Write(regionData, 0, regionData.Length);
                }
            }
        }


        public byte[] LoadRegionData(string saveName, Vector2Int regionLocalCoord)
        {
            byte[] regionData;
            string regionFileName = CoordToFileName(regionLocalCoord);
            using (FileStream fs = File.Open(_setting.SaveDirectoryDataRootPath + "/" + saveName + _setting.ChunkDirectoryDataPath + "/" + regionFileName, FileMode.Open)) 
            {
                regionData = new byte[fs.Length];
                fs.Read(regionData);
            }
            return regionData;
        }


        private string CoordToFileName(Vector2Int regionCoord)
        {
            string str = string.Format("R_{0}_{1}.rd", regionCoord.x, regionCoord.y);
            return str;
        }

        #endregion
    }
}